package it.blueocean.acanto.platform.service.impl;

import it.blueocean.acanto.entities.platform.MenuItem;
import it.blueocean.acanto.platform.dao.NavigationDao;
import it.blueocean.acanto.platform.service.NavigationService;
import it.blueocean.acanto.taglibrary.jsp.taglib.navigation.MenuList;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.GrantedAuthority;

@Named("navigationService")
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class NavigationServiceImpl implements NavigationService
{
	private final static Logger logger = LoggerFactory.getLogger(NavigationServiceImpl.class);

	@Inject
	@Named("acantoCacheManager")
	private CacheManager cacheManager;

	@Inject
	@Named("navigationDao")
	private NavigationDao navigationDao;

	private final String CACHE_MENU_ITEMS_KEY = "CACHE_MENU_ITEMS";

	private final String CACHE_DATA_KEY = "CACHE_DATA_MENU_ITEMS";

	@Override
	public MenuList getFilteredMenu(Collection<GrantedAuthority> roles)
	{
		MenuList menulist = new MenuList();
		
		List<MenuItem> menuItems = retrieveMenuItems();
		
		for (MenuItem menuItem : menuItems)
		{
			if(menuItem.isItemVisible(roles) && menuItem.isEnabled())
			{
				menulist.add(menuItem.clone());
			}
		}
		
		menulist.buildTree();
		
		return menulist;
	}
	
	/**
	 * @deprecated
	 * @return
	 */
	@SuppressWarnings("unused")
	private List<MenuItem> retrieveMenuItemsSimple()
	{
		List<MenuItem> menuItems = new ArrayList<MenuItem>();

		menuItems.addAll(navigationDao.loadMenuItems());

		return menuItems;
	}
	
	@SuppressWarnings("unchecked")
	private List<MenuItem> retrieveMenuItems()
	{
		List<MenuItem> menuItems = new ArrayList<MenuItem>();
		
		Cache cacheMenuItems = cacheManager.getCache(CACHE_MENU_ITEMS_KEY);

		if(cacheMenuItems != null)
		{
			logger.info("Cache Config. Found: " + cacheMenuItems.getName());

			final Element cacheElement = cacheMenuItems.get(CACHE_DATA_KEY);

			if(cacheElement != null)
			{
				logger.info("Cache Element Found");
				menuItems = (List<MenuItem>) cacheElement.getValue();
				logger.info("Using Cached Element for methodReturn.");
			}
			else
			{
				menuItems.addAll(navigationDao.loadMenuItems());
				final Element newCacheElement = new Element(CACHE_DATA_KEY, (Serializable) menuItems);
				cacheMenuItems.put(newCacheElement);
				logger.info("Created new CacheElement entry and stored in cache.");
			}
		}
		
		return menuItems;
	}

}
